package com.mijie.homi.search.service.index;

import java.io.File;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.IntField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.NIOFSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.BigramAnalyzer;

import com.mijie.core.ApplicationProperties;
import com.mijie.homi.common.domain.SearchResult;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.search.service.mood.MoodService;
import com.mijie.homi.search.util.ServerHelper;

@Service
public class UserIndexService extends AbstractIndexService{

	@Autowired
	private MoodService moodService;
	
	private static Logger logger = Logger.getLogger(UserIndexService.class);
	private static Version version = Version.LUCENE_43;
	private static Analyzer bigramAnalyzer = new BigramAnalyzer();
	private static String userIndexDir =  ApplicationProperties.get("resource.path")+ApplicationProperties.get("user.index.home");
	
	@Override
	protected void reIndexBefore() {
		
	}
	
	static FieldType dontStoreButTokenized = new FieldType();
	static{
		dontStoreButTokenized.setIndexed(true);
		dontStoreButTokenized.setStored(false);
		dontStoreButTokenized.setOmitNorms(true);
		dontStoreButTokenized.setTokenized(true);
		dontStoreButTokenized.freeze();
	}
	
	public void RAMIndex(int userId,String nickName){
		Document doc = new Document();
		doc.add(new Field("nickName",nickName.trim(),dontStoreButTokenized));
		doc.add(new IntField("id",userId,IntField.TYPE_STORED));
		indexDocToRAM(doc);
		logger.info("RAMIndex index user id:"+userId+",nickName:"+nickName);
	}
	
	
	@Override
	protected void index() throws Exception{
		IndexWriterConfig config = new IndexWriterConfig(this.version, getAnalyzer());
		config.setOpenMode(OpenMode.CREATE);
		config.setMaxBufferedDocs(1024*5);
		long currentTimeMillis = System.currentTimeMillis();
		String indexDirPath = getIndexDir()+currentTimeMillis;
		
		File indexDirFile = new File(indexDirPath);
		Directory indexDir = new NIOFSDirectory(indexDirFile);
		IndexWriter indexWriter  = new IndexWriter(indexDir,config);
		
		logger.info("=========================index user begin!!===============================");
		logger.info("user index file -> "+indexDirFile.getAbsolutePath());
		
		List<User> list = null;
		int limit = 1000;
		Document doc = null;
		Connection conn = ServerHelper.getConnection();
		Statement stmt = conn.createStatement();
		ResultSet rs = null;
		int offset = 0;
		boolean next = true;
		int size = 0;
		while(next){
			rs = stmt.executeQuery("select id,nickName from user limit "+offset+","+limit);
			while(rs.next()){
				doc = new Document();
				doc.add(new Field("nickName",rs.getString("nickName").trim(),dontStoreButTokenized));
				doc.add(new IntField("id",rs.getInt("id"),IntField.TYPE_STORED));
				indexWriter.addDocument(doc);
				size++;
			}
			next = size>0;
			offset+=limit;
			size = 0;
			rs.close();
		}
		indexWriter.commit();
		indexWriter.close();
		if(stmt!=null) stmt.close();
		if(conn!=null) conn.close();
		indexDone(indexDirFile);
		logger.info("=========================index user done!!===============================");
	}
	
	public SearchResult search(String idxf,int offset,int limit,String keyword) throws Exception{
		int keywordLength = keyword.length();
		Query query = null;
		if(keywordLength == 1){
			query = new TermQuery(new Term("nickName",keyword.toLowerCase()));
		}else if(keywordLength > 1){
			query = new BooleanQuery();
			TermQuery tq = null;
			TokenStream ts = getAnalyzer().tokenStream("nickName", new StringReader(keyword));
			ts.reset();
			CharTermAttribute term = ts.getAttribute(CharTermAttribute.class);
			while(ts.incrementToken()){
				tq = new TermQuery(new Term("nickName",term.toString()));
				((BooleanQuery) query).add(tq, Occur.MUST);
			}
		}
		return search(idxf,offset,limit,query,null);
	}
	

	@Override
	public Analyzer getAnalyzer() {
		return bigramAnalyzer;
	}

	@Override
	public String getIndexDir() {
		return userIndexDir;
	}


	@Override
	protected Object makeResultItem(String idxf, float socre,Document doc) {
		return Integer.parseInt(doc.get("id"));
	}


	@Override
	protected void reIndexDone() {
		// TODO Auto-generated method stub
		
	}
	
}
